package com.eat.fish_service.controller.web;

import com.eat.common_utils.CheckCodeUtil;
import com.eat.common_utils.MD5;
import com.eat.common_utils.R;
import com.eat.fish_service.entity.Dao.User;
import com.eat.fish_service.entity.ExpertCheck;
import com.eat.fish_service.entity.UserQuery;
import com.eat.fish_service.entity.VO.AquariumIds;
import com.eat.fish_service.entity.VO.UserVo;
import com.eat.fish_service.entity.newManager;
import com.eat.fish_service.service.AquariumService;
import com.eat.fish_service.service.ExpertCheckService;
import com.eat.fish_service.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author CZF
 * @create 2022-04-22 14:51
 */

@RestController("webUserController")
@CrossOrigin
@RequestMapping("/web/user")
@Slf4j
@Api(tags = "web用户接口")
public class UserController {

    @Autowired
    private ExpertCheckService expertCheckService;

    @Autowired
    UserService userService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    AquariumService aquariumService;

    @ApiOperation("注册接口，5个参数必填：1.username 2.password 3.realName(真实姓名) 4.phone（电话号码） 5.email（邮箱）")
    @PostMapping("register")
    public R register(@RequestBody User user) {
        return userService.register(user);
    }


    //返回二维码
    @ApiOperation("获取图片验证码")
    @GetMapping("getCode/{username}")
    public void getCode(@PathVariable("username") String username, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取验证码
        String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, response.getOutputStream(), 4);
        log.info("验证码为：" + checkCode);
        // 将验证码存入到reids中
        redisTemplate.opsForValue().set(username, checkCode, 2, TimeUnit.MINUTES);
    }

    //验证二维码
    @ApiOperation("验证验证码")
    @GetMapping("checkCode/{checkCode}/{username}")
    public R checkCode(@PathVariable(value = "checkCode") String checkCode, @PathVariable("username") String username) {
        log.info("要校验的验证码为：");
        log.info(checkCode);
        System.out.println("验证码是否正确：" + checkCode.equalsIgnoreCase(redisTemplate.opsForValue().get(username)));

        // 检测验证码是否一致
        if (checkCode.equalsIgnoreCase(redisTemplate.opsForValue().get(username))) {
            // 验证码正确
            return R.ok();
        }
        return R.error().message("验证码错误");
    }


    //登录接口,1.需要生成token存入redis中 2.成功则返回token，失败则返回失败原因 3.浏览器将token存入localstorage中
    @ApiOperation("登录接口")
    @PostMapping("login")
    public R login(@RequestBody UserVo userVo, HttpServletRequest request, HttpServletResponse response) {
        return userService.webLogin(userVo, request, response);
    }

    /**
     * 上传头像
     */
    @ApiOperation(value = "根据用户id上传用户头像")
    @PostMapping("uploadAvater/{id}")
    public R uploadAvater(@RequestBody MultipartFile pic,
                          @PathVariable("id") String id) {
        return userService.uploadAvater(pic, id);
    }

    /**
     * 用户添加鱼缸：直接通过鱼缸id来添加进“我的水族箱”，注意与“管理员添加鱼缸区分”！
     * 如果 添加鱼缸 或 鱼缸重启，用户输入鱼缸的id，可以从数据库中查找该鱼缸的ip和port，然后连接该鱼缸
     */
    @ApiOperation(value = "用户添加鱼缸/重启鱼缸，参数1：鱼缸id 参数2：用户名,如果请求报错含有Connection refused，表示鱼缸的系统未开启或者鱼缸id错误，添加鱼缸失败")
    @GetMapping("add_or_restart/{aquariumId}/{username}")
    public R addOrRestart(@PathVariable("aquariumId") Long aquariumId, @PathVariable("username") String username) {
        return aquariumService.addOrRestart(aquariumId, username);
    }

    /**
     * 用户删除鱼缸
     */
    @ApiOperation(value = "用户删除鱼缸，参数1：用户名；参数2：鱼缸id数组")
    @PostMapping("delUserAquarium/{username}")
    public R delUserAquarium(@PathVariable("username") String username, @RequestBody AquariumIds aquariumIds) {
        return aquariumService.delUserAquarium(username, aquariumIds);
    }

    /**
     * 用户在基本设置中修改用户信息
     */
    @ApiOperation(value = "基本设置中修改用户信息")
    @PostMapping("updateUserMes")
    public R updateUserMes(@RequestBody User user) {
        return userService.updateUserMes(user);
    }

    /**
     * 用户在安全设置中修改密码
     */
    @ApiOperation(value = "安全设置中修改密码")
    @GetMapping("sendCode/{to}/{id}")
    public R sendCode(@PathVariable("to") String to, @PathVariable("id") String id, HttpSession session) {
        return userService.sendCode(to, id, session);
    }

    /**
     * 安全设置中，修改密码的验证
     */
    @ApiOperation(value = "安全设置中修改密码")
    @PostMapping("judgeCode/{code}")
    public R judgeCode(@PathVariable("code") String code, @RequestBody User user, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) {
            return R.error().message("验证码未发送");
        }
        String code1 = (String) session.getAttribute(user.getId());
        if (code1.equals(code)) {
            user.setPassword(MD5.encrypt(user.getPassword()));
            userService.saveOrUpdate(user);
            session.invalidate(); //修改完后，删除该session
            return R.ok().message("验证通过，成功修改密码");
        }
        return R.error().message("验证码错误，请重新输入");
    }

    /**
     * 用户忘记密码 重新设置新密码
     * 需要进行绑定邮箱验证码验证
     */
    @ApiOperation(value = "找回密码中发送验证码")
    @GetMapping("findSendCode/{to}/{id}")
    public R findSendCode(@PathVariable("to") String to, @PathVariable("id") String id, HttpSession session) {
        return userService.findSendCode(to, id, session);
    }

    /**
     * 忘记密码中 验证验证码
     */
    @ApiOperation(value = "找回密码中验证验证码")
    @PostMapping("findJudgeCode/{code}")
    public R findJudgeCode(@PathVariable("code") String code, @RequestBody User user, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) {
            return R.error().message("验证码未发送");
        }
        String code1 = (String) session.getAttribute(user.getId());
        if (code1.equals(code)) {
            user.setPassword(MD5.encrypt(user.getPassword()));
            userService.saveOrUpdate(user);
            session.invalidate(); //修改完后，删除该session
            return R.ok().message("验证通过，已设置新密码");
        }
        return R.error().message("验证码错误，请重新输入");
    }

//    /**
//     * 用户发起专家审核
//     * 将该用户添加到审核表
//     */
//    @ApiOperation(value = "用户发起专家审核申请，将用户添加到专家审核序列")
//    @PostMapping("addExpertCheck")
//    public R addExpertCheck(@RequestBody ExpertCheck expertCheck){
//        return expertCheckService.addExpertCheck(expertCheck);
//    }

    //普通用户
    @ApiOperation(value = "普通用户带条件分页查询")
    @PostMapping("getUser/{current}/{size}")
    public R findUserCondition(@PathVariable
                               @ApiParam(name = "current", value = "当前页", required = true) Long current,
                               @PathVariable
                               @ApiParam(name = "size", value = "每页显示条数", required = true) Long size,
                               @RequestBody(required = false)
                               @ApiParam(name = "UserQuery", value = "查询对象条件，普通用户真实姓名模糊查询，电话等值查询，时间范围查询", required = false) UserQuery query) {
        return userService.findUserCondition(current, size, query);
    }

    //专家
    @ApiOperation(value = "专家带条件分页查询")
    @PostMapping("getExpert/{current}/{size}")
    public R findExpertCondition(@PathVariable
                                 @ApiParam(name = "current", value = "当前页", required = true) Long current,
                                 @PathVariable
                                 @ApiParam(name = "size", value = "每页显示条数", required = true) Long size,
                                 @RequestBody(required = false)
                                 @ApiParam(name = "UserQuery", value = "查询对象条件，专家真实姓名模糊查询，电话等值查询，时间范围查询", required = false) UserQuery query) {
        return userService.findExpertCondition(current, size, query);
    }

    //管理员
    @ApiOperation(value = "管理员带条件分页查询")
    @PostMapping("getManager/{current}/{size}")
    public R findManagerCondition(@PathVariable
                                  @ApiParam(name = "current", value = "当前页", required = true) Long current,
                                  @PathVariable
                                  @ApiParam(name = "size", value = "每页显示条数", required = true) Long size,
                                  @RequestBody(required = false)
                                  @ApiParam(name = "UserQuery", value = "查询对象条件，管理员真实姓名模糊查询，电话等值查询，时间范围查询", required = false) UserQuery query) {
        return userService.findManagerCondition(current, size, query);
    }

    //添加管理员
    @ApiOperation(value = "添加管理员或超级管理员")
    @PostMapping("addManager/{status}")
    public R addManager(@PathVariable
                        @ApiParam(name = "status", value = "身份：传数字3位管理员，传4为超级管理员", required = true) Integer status,
                        @RequestBody(required = true)
                        @ApiParam(name = "newManage", value = "新添管理员或超级管理员的信息, 用户头像可以选填", required = true) newManager newManager) {
        return userService.addManager(newManager, status);
    }

    //删除管理员
    @ApiOperation(value = "按id删除管理员")
    @GetMapping("deleteManager/{userId}")
    public R deleteMahager(@PathVariable String userId) {
        return userService.deleteManager(userId);
    }
}
